using System;

namespace RapidHDL
{
	/// <summary>
	/// Summary description for Utility.
	/// </summary>
	public class Utility
	{
		public Utility()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		public static string StringRepeat(string poBaseString, int piRepeat)
		{
			string sResult = "";

			if (poBaseString.Length == 1)
				return sResult.PadLeft(piRepeat,poBaseString[0]);
			
			for (int iIndex = 0; iIndex < piRepeat; iIndex++)
			{
				sResult += piRepeat;
			}
			return sResult;
		}

        public static int WidestNodeVector(NodeVector pnNodeVectorA, NodeVector pnNodeVectorB)
        {
            if (pnNodeVectorA.Nodes.Count > pnNodeVectorB.Nodes.Count)
                return pnNodeVectorA.Nodes.Count;
            else
               return pnNodeVectorB.Nodes.Count;

        }

        public static string StringTakeRightFromEnd(string psString, char pcDelimit)
        {
            string[] saDelimt = psString.Split(pcDelimit);

            if (saDelimt.Length <= 1)
                return "";

            return saDelimt[saDelimt.Length - 1];
        }

        public static string StringTakeLeftFromEnd(string psString, char pcDelimit)
        {
            string[] saDelimit = psString.Split(pcDelimit);

            if (saDelimit.Length == 0)
                return "";

            if (saDelimit.Length == 1)
                return saDelimit[0];

            return psString.Substring(0, psString.Length - saDelimit[saDelimit.Length - 1].Length - 1);
        }

        public static string StringTakeLeftFromStart(string psString, char pcDelimit)
        {
            string[] saDelimit = psString.Split(pcDelimit);

            if (saDelimit.Length == 0)
                return "";

            return saDelimit[0];
        }

        public static string StringTakeRightFromStart(string psString, char pcDelimit)
        {
            string[] saDelimit = psString.Split(pcDelimit);

            if (saDelimit.Length <= 1)
                return "";

            return psString.Substring(saDelimit[0].Length + 1, psString.Length - saDelimit[0].Length - 1);
        }

        public static void SinkExtraBits(Component poComponent, NodeVector poNodeVector)
        {
            //Component oComponent = poNodeVector.ParentComponent;
            int iSinkBits = 0;
            foreach (Node oNode in poNodeVector.Nodes)
            {
                if (oNode.Net.SinkNodes.Count == 0)
                {
                    iSinkBits++;
                }
            }

            if (iSinkBits == 0)
                return;

            //JNA - June 18 - switching these two lines, because it makes sense... might break something
            SignalTerminator oSink = new SignalTerminator(poComponent,poNodeVector.Name + "_terminate",iSinkBits);
            //NodeVector oSink = new NodeVector(poComponent, poNodeVector.Name + "_terminate", iSinkBits,NodeFlowType.Sink);
            
            iSinkBits = 0;
            foreach (Node oNode in poNodeVector.Nodes)
            {
                if (oNode.Net.SinkNodes.Count == 0)
                {
                    //oNode.Net.Connect(oSink.InputNodes[iSinkBits].Net);
                    oNode.Net.Connect(oSink.InputNodes[iSinkBits].Net);
                    iSinkBits++;
                }
            }
        }


        public static void SourceExtraBits(Component poComponent, NodeVector poNodeVector,NodeState pnsConstantValue)
        {
            //Component oComponent = poNodeVector.ParentComponent;
            int iSourceBits = 0;
            foreach (Node oNode in poNodeVector.Nodes)
            {
                if (oNode.Net.SourceNodes.Count == 0)
                {
                    iSourceBits++;
                }
            }

            if (iSourceBits == 0)
                return;

            char cValue = 'x';
            switch (pnsConstantValue)
            {
                case NodeState.High:
                    cValue = '1';
                    break;
                case NodeState.Low:
                    cValue = '0';
                    break;
                case NodeState.Tri:
                    cValue = 'z';
                    break;
                case NodeState.Undefined:
                    cValue = 'x';
                    break;
                default:
                    System.Diagnostics.Debug.Fail("Unexpected constant input to SourceExtraBits");
                    break;
            }
            string sValue = new string(cValue,iSourceBits);

            Constant oSource = new Constant(poComponent, poNodeVector.Name + "_extra_bits",sValue);
            iSourceBits = 0;
            foreach (Node oNode in poNodeVector.Nodes)
            {
                if (oNode.Net.SourceNodes.Count == 0)
                {
                    oNode.Net.Connect(oSource.OutputNodes[iSourceBits].Net);
                    iSourceBits++;
                }
            }
        }

        public static string NormalizePath(string psPath)
        {
            if (psPath[psPath.Length - 1] != '\\')
                return psPath + "\\";
            else
                return psPath;
        }

        public static void Print(string psValue, int piIndent)
        {
            System.Console.WriteLine(new String(' ', piIndent * 3) + psValue);
        }

        public static void Print(string psValue)
        {
            Print(psValue, 0);
        }

        public static object GetFirstHashtableKey(System.Collections.Hashtable poHT)
        {
            foreach (object oKey in poHT.Keys)
            {
                return oKey;
            }
            return null;
        }

        public static bool IsUnix()
        {
            int p = (int)Environment.OSVersion.Platform;
            if ((p == 4) || (p == 128))
                return true;

            return false;
        }

        public static string ReduceSpaces(string psValue)
        {
            string sValue = psValue.Trim();
            while (sValue.Contains("  "))
                sValue = sValue.Replace("  ", " ");
            return sValue.Trim();
        }

        public static int Count(string psValue, string psSearchFor)
        {
            int iCount = 0;
            int iStartIdx = 0;
            int iFoundIdx = 0;
            iFoundIdx = psValue.IndexOf(psSearchFor, iStartIdx);
            while (iFoundIdx >= 0)
            {
                iCount++;
                iStartIdx = iFoundIdx + 1;
                iFoundIdx = psValue.IndexOf(psSearchFor, iStartIdx);            
            }
            return iCount;
        }
	}
}
